﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Domain.Core;
using Domain.MainModule.Entities;
using Domain.Core.Specification;
using Domain.MainModule.CustomerCompanies;

namespace Application.MainModule.CustomerCompaniesManagement
{
    public class CustomerCompanyManagementService: ICustomerCompanyManagementService, IDisposable
    {
        #region Members

        ICustomerCompanyRepository _CustomerCompanyRepository;

        #endregion

        #region Constructor

        /// <summary>
        /// Default constructor for CustomerCompanyService
        /// </summary>
        /// <param name="customerCompanyRepository">CustomerCompanyRepository dependency, usually this is resolver with IoC</param>
        public CustomerCompanyManagementService(ICustomerCompanyRepository customerCompanyRepository)
        {
            if (customerCompanyRepository == (ICustomerCompanyRepository)null)
                throw new ArgumentNullException(Resources.Messages.exception_DependenciesAreNotInitialized);

            _CustomerCompanyRepository = customerCompanyRepository;
        }

        #endregion

        public void AddCustomerCompany(CustomerCompany customerCompany)
        {
            if (customerCompany.UserId == null)
                throw new ArgumentNullException(Resources.Messages.exception_InvalidUserId, "customerCompany.UserId");

            customerCompany.UserId = Guid.NewGuid();

            IUnitOfWork unitOfWork = _CustomerCompanyRepository.UnitOfWork as IUnitOfWork;
            _CustomerCompanyRepository.Add(customerCompany);
            unitOfWork.Commit();
        }

        public void ChangeCustomerCompany(CustomerCompany customerCompany)
        {
            IUnitOfWork unitOfWork = _CustomerCompanyRepository.UnitOfWork as IUnitOfWork;
            _CustomerCompanyRepository.Modify(customerCompany);
            unitOfWork.CommitAndRefreshChanges();
        }

        public void RemoveCustomerCompany(CustomerCompany customerCompany)
        {
            if (customerCompany == (CustomerCompany)null)
                throw new ArgumentNullException("customerCompany");

            IUnitOfWork unitOfWork = _CustomerCompanyRepository.UnitOfWork as IUnitOfWork;
            customerCompany.IsEnabled = false;
            _CustomerCompanyRepository.Modify(customerCompany);
            unitOfWork.CommitAndRefreshChanges();
        }

        public CustomerCompany FindCustomerCompanyByMembershipUserId(Guid userId)
        {
            if (userId == null)
                throw new ArgumentNullException(Resources.Messages.exception_InvalidUserId, "customerCompany.UserId");

            CustomerCompanyMembershipUserIdSpecification spec = new CustomerCompanyMembershipUserIdSpecification(userId);
            return _CustomerCompanyRepository.FindCustomerCompany(spec);
        }

        public CustomerCompany FindCustomerCompanyById(Guid userId)
        {
            if (userId == null)
                throw new ArgumentNullException(Resources.Messages.exception_InvalidUserId, "customerCompany.UserId");

            CustomerCompanyUserIdSpecification spec = new CustomerCompanyUserIdSpecification(userId);
            return _CustomerCompanyRepository.FindCustomerCompany(spec);
        }

        #region IDisposable

        /// <summary>
        /// Dispose associated context with this domain service
        /// </summary>
        public void Dispose()
        {
            if (_CustomerCompanyRepository != null
                &&
                _CustomerCompanyRepository.UnitOfWork != null)
            {
                _CustomerCompanyRepository.UnitOfWork.Dispose();
            }
        }

        #endregion

        public List<CustomerCompany> FindPagedCustomerCompanies(int pageIndex, int pageCount)
        {
            if (pageIndex < 0)
                throw new ArgumentException(Resources.Messages.exception_InvalidPageIndex, "pageIndex");

            if (pageCount <= 0)
                throw new ArgumentException(Resources.Messages.exception_InvalidPageCount, "pageCount");

            return _CustomerCompanyRepository.GetPagedCustomerCompanies(pageIndex, pageCount).ToList();

        }
    }
}
